/**
 * @file crtsurfdata2.cpp
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2024-04-19
 *
 * @copyright Copyright (c) 2024
 *
 */
#include <iostream>
#include "../../public/_public.h"
#include <vector>

// 站点参数数据
struct st_stcode
{
    /* data */
    char provname[31]; // 省
    char obtid[11];    // 站号
    char obtname[31];  // 站名
    double lat;        // 纬度
    double lon;        // 经度
    double height;     // 海拔高度
};

// 气象数据
struct st_surfdata
{
    char obtid[11];     // 站点代码。
    char ddatetime[21]; // 数据时间：格式yyyymmddhh24miss
    int t;              // 气温：单位，0.1摄氏度。
    int p;              // 气压：0.1百帕。
    int u;              // 相对湿度，0-100之间的值。
    int wd;             // 风向，0-360之间的值。
    int wf;             // 风速：单位0.1m/s
    int r;              // 降雨量：0.1mm。
    int vis;            // 能见度：0.1米。
};

CLogFile logfile;
std::vector<struct st_stcode> vstcode;
std::vector<struct st_surfdata> vsurfdata;

/**
 * @brief 加载站点参数
 *
 * @param inifile 站点参数文件，建议使用绝对路径
 * @return true
 * @return false
 */
// 把站点参数文件中加载到vstcode容器中。
bool LoadSTCode(const char *inifile);

// 模拟生成全国气象站点分钟观测数据，存放在vsurfdata容器中。
void CrtSurfData();

int main(int argc, char *argv[])
{

    // 参>4
    if (argc != 4)
    {
        // 不能
        printf("Example: ./crtsurfdata1 inifile outpath logfile\n");
        printf("Example: ./crtsurfdata1 stcode.ini ./out log.txt\n");

        printf("inifile: 全国气象站点的参数，站点的位置\n");
        printf("outpath: 站点数据生成的位置\n");
        printf("inifile: 日志位置\n");
        return -1;
    }

    // 日志文件写东西。打开日志
    if (logfile.Open(argv[3], "a+", false))
    {
        // 写日志
        logfile.Write("第一次记录日志\n");
        logfile.WriteEx("第一次记录日志\n");

        if (LoadSTCode(argv[1]))
        {
            std::cout << "加载完成\n"
                      << std::endl;
        }
        else
        {
            std::cout << "加载失败\n"
                      << std::endl;
            return -1;
        }

        // 生成每一个站点的气象数据---->Vector<st_surfdata>
        CrtSurfData();
    }
    else
    {
        // 日志失败
        printf("打开日志失败");
        return -1;
    }

    return 0;
}

bool LoadSTCode(const char *inifile)
{
    // 首先打开这个文件
    // 循环读
    // 分割
    // 写入一个结构体
    // 结构体存放到vector

    CFile File;
    CCmdStr CmdStr;
    struct st_stcode stcode;

    if (File.Open(inifile, "r"))
    {
        char strBuffer[301];
        memset(strBuffer, 0, 301);

        // 初始化
        while (true)
        {
            // 读取，检查是否退出
            if (File.Fgets(strBuffer, 300, true))
            {
                // 切割字符串strBuffer,','和“,”
                CmdStr.SplitToCmd(strBuffer, ",", true);
                if (CmdStr.CmdCount() != 6)
                    continue;
                // 存放到机构提
                // bool GetValue(const int inum,char *value,const int ilen=0); // 字符串，ilen缺省值为0。

                CmdStr.GetValue(0, stcode.provname, 30); // 省
                CmdStr.GetValue(1, stcode.obtid, 10);    // 站号
                CmdStr.GetValue(2, stcode.obtname, 30);  // 站名
                CmdStr.GetValue(3, &stcode.lat);         // 纬度
                CmdStr.GetValue(4, &stcode.lon);         // 经度
                CmdStr.GetValue(5, &stcode.height);      // 海拔高度

                // 个人建议：用完之后，去清空，为下一次循环做准备
                logfile.Write(stcode.provname, stcode.obtid);
                vstcode.push_back(stcode);
                memset((void *)&stcode, 0, sizeof(struct st_stcode));
                // memset((void*) &stcode,0,301);
            }
            else
            {
                // 日志
                // logfile.Write("读取站点参数数据失败\n");
                break;
            }
        }
        return true;
    }
    else
    {
        logfile.Write("读取站点参数数据失败\n");
        return false;
    }
}

/*
//气象数据
struct st_surfdata
{
  char obtid[11];      // 站点代码。
  char ddatetime[21];  // 数据时间：格式yyyymmddhh24miss
  int  t;              // 气温：单位，0.1摄氏度。
  int  p;              // 气压：0.1百帕。
  int  u;              // 相对湿度，0-100之间的值。
  int  wd;             // 风向，0-360之间的值。
  int  wf;             // 风速：单位0.1m/s
  int  r;              // 降雨量：0.1mm。
  int  vis;            // 能见度：0.1米。
};
*/
void CrtSurfData()
{

    // 读取每一个站点，为每一个站点生成气象数据，然后存储到vector

    // 初始化种子
    srand(time(0));

    // 时间操作,"yyyymmddhh24miss"
    char strddatetime[21];
    memset(strddatetime, 0, 21);
    LocalTime(strddatetime, "yyyymmddhh24miss");

    struct st_surfdata stsurfdata;
    memset(&stsurfdata, 0, sizeof(struct st_surfdata));
    for (size_t i = 0; i < vstcode.size(); i++)
    {
        // 生成每一个站点的气象参数
        strncpy(stsurfdata.obtid, vstcode[i].obtid, 11);
        strncpy(stsurfdata.ddatetime, strddatetime, 21);
        // 随机生成，存储
        stsurfdata.t = rand() % 351;             // 气温：单位，0.1摄氏度
        stsurfdata.p = rand() % 265 + 10000;     // 气压：0.1百帕
        stsurfdata.u = rand() % 100 + 1;         // 相对湿度，0-100之间的值。
        stsurfdata.wd = rand() % 360;            // 风向，0-360之间的值。
        stsurfdata.wf = rand() % 150;            // 风速：单位0.1m/s
        stsurfdata.r = rand() % 16;              // 降雨量：0.1mm
        stsurfdata.vis = rand() % 5001 + 100000; // 能见度：0.1米
        vsurfdata.push_back(stsurfdata);
        memset(&stsurfdata, 0, sizeof(struct st_surfdata));
    }
    // for (auto i:vstcode)
    // {

    // }
}

// 定义状态
// 初始化状态
// while
// 当前时刻状态更新
// 求输出
// 历史状态更新一次循环重置中间状态
// 为下

// 检查是否退出递归
// 输出
// 为下一次递归做准备，设定好中间状态

/*
递归：其实是要为了下一次递归做准备，所以会把状态进行变化

状态：迭代过程中，会不断由之前状态更新的东西，携带了当前迭代层的信息
输出：由状态组成或者形成，要被记录的
中间状态变量：不需要传递到下一层的，只是用来辅助生成输出的


初始化
while
新状态更新
使用中间状态和新状态和历史状态输出
更新旧状态
恢复中间状态，下一次迭代做准备

*/
